home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / gs24src.zip / GSCIE.C < prev    next >
C/C++ Source or Header  |  1992-02-09  |  7KB  |  243 lines

  1. /* Copyright (C) 1992 Aladdin Enterprises.  All rights reserved.
  2.    Distributed by Free Software Foundation, Inc.
  3.  
  4. This file is part of Ghostscript.
  5.  
  6. Ghostscript is distributed in the hope that it will be useful, but
  7. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  8. to anyone for the consequences of using it or for whether it serves any
  9. particular purpose or works at all, unless he says so in writing.  Refer
  10. to the Ghostscript General Public License for full details.
  11.  
  12. Everyone is granted permission to copy, modify and redistribute
  13. Ghostscript, but only under the conditions described in the Ghostscript
  14. General Public License.  A copy of this license is supposed to have been
  15. given to you along with Ghostscript so you can know your rights and
  16. responsibilities.  It should be in a file named COPYING.  Among other
  17. things, the copyright notice and this notice must be preserved on all
  18. copies.  */
  19.  
  20. /* gscie.c */
  21. /* CIE color algorithms for Ghostscript */
  22. #include "std.h"
  23. #include "gscie.h"
  24.  
  25. /* Default values for components. */
  26. private float
  27. fp_identity(floatp value)
  28. {    return (float)value;
  29. }
  30. gs_range3 Range3_default = { {0,1}, {0,1}, {0,1} };
  31. gs_float_proc3 Decode3_default = { fp_identity, fp_identity, fp_identity };
  32. gs_matrix3 Matrix3_default = { {1,0,0}, {0,1,0}, {0,0,1} };
  33. gs_range RangeA_default = {0,1};
  34. gs_float_proc DecodeA_default = fp_identity;
  35. gs_vector3 MatrixA_default = { 1, 1, 1 };
  36. gs_vector3 BlackPoint_default = { 0, 0, 0 };
  37.  
  38. /* Apply procedures to a vector. */
  39. private void
  40. cie_apply3(gs_vector3 *in, gs_float_proc3 *procs, gs_vector3 *out)
  41. {    out->u = (*procs->u)(in->u);
  42.     out->v = (*procs->v)(in->v);
  43.     out->w = (*procs->w)(in->w);
  44. }
  45.  
  46. /* Multiply a vector by a matrix. */
  47. private void
  48. cie_mult3(gs_vector3 *in, register gs_matrix3 *mat, gs_vector3 *out)
  49. {    float u = in->u, v = in->v, w = in->w;
  50.     out->u = (u * mat->cu.u) + (v * mat->cu.v) + (w * mat->cu.w);
  51.     out->v = (u * mat->cv.u) + (v * mat->cv.v) + (w * mat->cv.w);
  52.     out->w = (u * mat->cw.u) + (v * mat->cw.v) + (w * mat->cw.w);
  53. }
  54.  
  55. /* Invert a matrix. */
  56. private void
  57. cie_invert3(register gs_matrix3 *in, register gs_matrix3 *out)
  58. {    /* This is a brute force algorithm; maybe there are better. */
  59.     /* We label the array elements */
  60.     /*   [ A B C ]   */
  61.     /*   [ D E F ]   */
  62.     /*   [ G H I ]   */
  63. #define A cu.u
  64. #define B cv.u
  65. #define C cw.u
  66. #define D cu.v
  67. #define E cv.v
  68. #define F cw.v
  69. #define G cu.w
  70. #define H cv.w
  71. #define I cw.w
  72.     double AE = in->A * in->E, AF = in->A * in->F,
  73.         AH = in->A * in->H, AI = in->A * in->I;
  74.     double BD = in->B * in->D, BF = in->B * in->F,
  75.         BG = in->B * in->G, BI = in->B * in->I;
  76.     double CD = in->C * in->D, CE = in->C * in->E,
  77.         CG = in->C * in->G, CH = in->C * in->H;
  78.     double DH = in->D * in->H, DI = in->D * in->I;
  79.     double EG = in->E * in->G, EI = in->E * in->I;
  80.     double FG = in->F * in->G, FH = in->F * in->H;
  81.     double coA = EI - FH, coB = FG - DI, coC = DH - EG;
  82.     double det = in->A * coA + in->B * coB + in->C * coC;
  83.     out->A = coA / det;
  84.     out->D = coB / det;
  85.     out->G = coC / det;
  86.     out->B = (CH - BI) / det;
  87.     out->E = (AI - CG) / det;
  88.     out->H = (BG - AH) / det;
  89.     out->C = (BF - CE) / det;
  90.     out->F = (CD - AF) / det;
  91.     out->I = (AE - BD) / det;
  92. #undef A
  93. #undef B
  94. #undef C
  95. #undef D
  96. #undef E
  97. #undef F
  98. #undef G
  99. #undef H
  100. #undef I
  101. }
  102.  
  103. /* Force values within bounds. */
  104. #define restrict(v, r)\
  105.   ((v) < (r).rmin ? (r).rmin : (v) > (r).rmax ? (r).rmax : (v))
  106. private void
  107. cie_restrict3(gs_vector3 *in, gs_range3 *range, gs_vector3 *out)
  108. {    float temp;
  109.     temp = in->u; out->u = restrict(temp, range->u);
  110.     temp = in->v; out->v = restrict(temp, range->v);
  111.     temp = in->w; out->w = restrict(temp, range->w);
  112. }
  113.  
  114. /* Decode ABC values to XYZ. */
  115. int
  116. gs_cie_abc_decode1(gs_vector3 *pabc, gs_vector3 *ptabc, gs_cie_abc *pcie)
  117. {    cie_restrict3(pabc, &pcie->RangeABC, ptabc);
  118.     return 0;
  119. }
  120. /*
  121.  * Client:
  122.     cie_apply3(ptabc, &pcie->DecodeABC, ptabc);
  123.  */
  124. int
  125. gs_cie_abc_decode2(gs_vector3 *ptabc, gs_vector3 *ptlmn, gs_cie_abc *pcie)
  126. {    cie_mult3(ptabc, &pcie->MatrixABC, ptlmn);
  127.     cie_restrict3(ptlmn, &pcie->RangeLMN, ptlmn);
  128.     return 0;
  129. }
  130. /*
  131.  * Client:
  132.     cie_apply3(ptlmn, &pcie->DecodeLMN, ptlmn);
  133.  */
  134. int
  135. gs_cie_abc_decode3(gs_vector3 *ptlmn, gs_vector3 *pxyz, gs_cie_abc *pcie)
  136. {    cie_mult3(ptlmn, &pcie->MatrixLMN, pxyz);
  137.     return 0;
  138. }
  139.  
  140. /* Decode an A value to XYZ. */
  141. int
  142. gs_cie_a_decode1(floatp va, float *pta, gs_cie_a *pcie)
  143. {    *pta = restrict(va, pcie->RangeA);
  144.     return 0;
  145. }
  146. /*
  147.  * Client:
  148.     ta = (*pcie->DecodeA)(*pta);
  149.  */
  150. int
  151. gs_cie_a_decode2(floatp ta, gs_vector3 *ptlmn, gs_cie_a *pcie)
  152. {    gs_vector3 lmn;
  153.     lmn.u = ta * pcie->MatrixA.u;
  154.     lmn.v = ta * pcie->MatrixA.v;
  155.     lmn.w = ta * pcie->MatrixA.w;
  156.     cie_restrict3(&lmn, &pcie->RangeLMN, ptlmn);
  157.     return 0;
  158. }
  159. /*
  160.  * Client:
  161.     cie_apply3(ptlmn, &pcie->DecodeLMN, ptlmn);
  162.  */
  163. /* gs_cie_a_decode3 is the same as gs_cie_abc_decode3. */
  164.  
  165. /* Initialize the computed fields of a CIE color rendering structure. */
  166. int
  167. gs_cie_render_init(gs_cie_render *pcie)
  168. {    cie_invert3(&pcie->MatrixPQR, &pcie->MatrixPQR_inverse);
  169.     cie_mult3(&pcie->points.WhitePoint, &pcie->MatrixPQR, &pcie->wdpqr);
  170.     cie_mult3(&pcie->points.BlackPoint, &pcie->MatrixPQR, &pcie->bdpqr);
  171.     return 0;
  172. }
  173.  
  174. /* Render CIE colors */
  175. int
  176. gs_cie_render_colors1(gs_vector3 *pxyz, gs_cie_wbsd *pwbsd, gs_vector3 *ptpqr, gs_cie_wb *points, gs_cie_render *pcie)
  177. {    cie_mult3(pxyz, &pcie->MatrixPQR, ptpqr);
  178.     pwbsd->ws.xyz = points->WhitePoint;
  179.     cie_mult3(&pwbsd->ws.xyz, &pcie->MatrixPQR, &pwbsd->ws.pqr);
  180.     pwbsd->bs.xyz = points->BlackPoint;
  181.     cie_mult3(&pwbsd->bs.xyz, &pcie->MatrixPQR, &pwbsd->bs.pqr);
  182.     pwbsd->wd.xyz = pcie->points.WhitePoint;
  183.     pwbsd->wd.pqr = pcie->wdpqr;
  184.     pwbsd->bd.xyz = pcie->points.BlackPoint;
  185.     pwbsd->bd.pqr = pcie->bdpqr;
  186.     return 0;
  187. }
  188. /*
  189.  * Client:
  190.     ptpqr->u = (*pcie->TransformPQR.u)(pwbsd, ptpqr->u);
  191.     ptpqr->v = (*pcie->TransformPQR.v)(pwbsd, ptpqr->v);
  192.     ptpqr->w = (*pcie->TransformPQR.w)(pwbsd, ptpqr->w);
  193.  */
  194. int
  195. gs_cie_render_colors2(gs_vector3 *ptpqr, gs_vector3 *ptlmn, gs_cie_render *pcie)
  196. {    gs_vector3 xyzd;
  197.     cie_mult3(ptpqr, &pcie->MatrixPQR_inverse, &xyzd);
  198.     cie_mult3(&xyzd, &pcie->MatrixLMN, ptlmn);
  199.     return 0;
  200. }
  201. /*
  202. /* Client:
  203.     cie_apply3(ptlmn, &pcie->EncodeLMN, ptlmn);
  204.  */
  205. int
  206. gs_cir_render_colors3(gs_vector3 *ptlmn, gs_vector3 *ptabc, gs_cie_render *pcie)
  207. {    gs_vector3 lmn;
  208.     cie_restrict3(ptlmn, &pcie->RangeLMN, &lmn);
  209.     cie_mult3(&lmn, &pcie->MatrixABC, ptabc);
  210.     return 0;
  211. }
  212. /*
  213.  * Client:
  214.     cie_apply3(ptabc, &pcie->EncodeABC, ptabc);
  215.  */
  216. int
  217. gs_cie_render_colors4(gs_vector3 *ptabc, float *colors, gs_cie_render *pcie)
  218. {    gs_vector3 abc;
  219.     cie_restrict3(ptabc, &pcie->RangeABC, &abc);
  220.     if ( pcie->RenderTable.table == 0 )
  221.        {    /* No further transformation */
  222.         colors[0] = abc.u;
  223.         colors[1] = abc.v;
  224.         colors[2] = abc.w;
  225.        }
  226.     else
  227.        {    /* Use the RenderTable. */
  228.         int m = pcie->RenderTable.m;
  229. #define ri(s,n)\
  230.   (int)((abc.s - pcie->RangeABC.s.rmin) * (pcie->RenderTable.n - 1) /\
  231.     (pcie->RangeABC.s.rmax - pcie->RangeABC.s.rmin) + 0.5)
  232.         int ia = ri(u, NA);
  233.         int ib = ri(v, NB);
  234.         int ic = ri(w, NC);
  235.         int j;
  236.         byte *pdc = pcie->RenderTable.table[ia] +
  237.             m * (ib * pcie->RenderTable.NC + ic);
  238.         for ( j = 0; j < m; j++ )
  239.             colors[j] = (*pcie->RenderTable.T[j])(pdc[j] / 255.0);
  240.        }
  241.     return 0;
  242. }
  243.